package com.tuanzi.loan.business.service.settlement.impl;

import com.base.common.log.LogService;
import com.tuanzi.loan.business.entity.CurrentUser;
import com.tuanzi.loan.business.entity.family.ProductInfo;
import com.tuanzi.loan.business.entity.settlement.CompanyInfo;
import com.tuanzi.loan.business.entity.settlement.FirstpartyDataChangeRecord;
import com.tuanzi.loan.business.entity.settlement.JfSltBackData;
import com.tuanzi.loan.business.entity.settlement.SettlementUvRecord;
import com.tuanzi.loan.business.repository.family.ProductInfoRepository;
import com.tuanzi.loan.business.repository.settlement.CompanyInfoRepository;
import com.tuanzi.loan.business.repository.settlement.JfBackDataRepository;
import com.tuanzi.loan.business.repository.settlement.SettlementUvRecordRepository;
import com.tuanzi.loan.business.service.settlement.JfBackDataService;
import com.tuanzi.loan.core.aspect.Debug;
import com.tuanzi.loan.core.service.CommonServiceImpl;
import com.tuanzi.server.loan_base.util.DateUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.retry.RetryException;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Debug
@Service
@Transactional
@Retryable(value = {RetryException.class})
public class JfBackDataServiceImpl extends CommonServiceImpl<JfSltBackData, Long> implements JfBackDataService {
    private static final Integer DAY = 0; //按日结算
    private static final Integer WEEK = 1; //按月结算
    private static final ThreadLocal<SimpleDateFormat> sdf = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));
    //合作模式
    private static final Integer CPA = 0;
    private static final Integer CPS = 1;
    private static final Integer CPC = 2;
    private static final Integer CPA_CPS = 3;

    @Autowired
    private JfBackDataRepository jfBackDataRepository;

    @Autowired
    private ProductInfoRepository productInfoRepository;

    @Autowired
    private CompanyInfoRepository companyInfoRepository;

    @Autowired
    private SettlementUvRecordRepository settlementUvRecordRepository;

    @Override
    public JfSltBackData createJfSltBackData(Integer type, Long companyId, Integer copMode) {
        if (null == type) {//默认为按日模式
            type = DAY;
        }

        //设置模式、创建者、时间等
        JfSltBackData jfSltBackData = getDataBeanInfo(type, companyId, copMode);
        return jfSltBackData;
    }

    @Override
    public List<JfSltBackData> getJfBackListInCurrWeekByType(Integer type, Long companyId) {
        if (null == type) {
            type = DAY;
        }
        List<String> days = getWeekByDate(new Date());
        if (null == days || days.size() < 2) {
            return null;
        }
        return jfBackDataRepository.getJfBackListInCurrWeekByType(type, days.get(0), days.get(1), companyId);
    }

    //补充数据
    private JfSltBackData getDataBeanInfo(Integer type, Long companyId, Integer copMode) {
        List<String> days = getWeekByDate(new Date());
        JfSltBackData jfSltBackData = new JfSltBackData();
        jfSltBackData.setCompanyId(companyId);
        jfSltBackData.setCreateTime(new Date());
        jfSltBackData.setCreateMan(CurrentUser.get().getName());
        jfSltBackData.setCopMode(copMode);
        jfSltBackData.setIsEdit(1); //默认是可编辑状态
        if (type == WEEK) {
            jfSltBackData.setBeginDate(DateUtils.formatStringDate(days.get(0) + " 00:00:00"));
            //String afterSixDays = DateUtils.getTimeAfterDays(6); //获取6天后的日期
            jfSltBackData.setEndDate(DateUtils.formatStringDate(days.get(1) + " 00:00:00"));
            jfSltBackData.setType(type);
        } else if (type == DAY) {
            jfSltBackData.setBeginDate(new Date());
            jfSltBackData.setEndDate(new Date());
            jfSltBackData.setType(type);
        }
        return jfSltBackData;
    }

    @Override
    public List<JfSltBackData> getCurWeekJfBackByCompanyId(Long companyId) {
        List<String> days = getWeekByDate(new Date());
        if (null == days || days.size() < 2) {
            return null;
        }
        return jfBackDataRepository.getJfBackListInCurrWeekByCompanyId(companyId, days.get(0), days.get(1));
    }

    @Override
    public String getCurWeekPingZhengUrlByList(List<JfSltBackData> jfSltBackDataList) {
        if (jfSltBackDataList.size() == 0) {
            return null;
        }

        for (JfSltBackData jfSltBackData : jfSltBackDataList) {
            if (StringUtils.isNotBlank(jfSltBackData.getPzUrl())) {
                return jfSltBackData.getPzUrl();
            }
        }

        return null;
    }

    @Override
    public List<JfSltBackData> updateJSBDListNotInDataBase(List<JfSltBackData> jfSltBackDataList, JfSltBackData jfSltBackData, CompanyInfo companyInfo) {
        //如果结算金额为空就按公式算
        if (jfSltBackData.getSltMoney() == null) {
            Integer copMode = companyInfo.getCopMode();
            double sltMoney = 0;
            if (copMode == CPA) {
                Float ratio = companyInfo.getSettlementPriceCpa(); //cpa是元
                Integer registerNum = jfSltBackData.getRegisterNum() == null ? 0 : jfSltBackData.getRegisterNum();
                sltMoney = registerNum * ratio; //注册数
            } else if (copMode == CPS) {
                Float ratio = companyInfo.getSettlementPriceCps(); //cps是百分比
                Double lendMoney = jfSltBackData.getLendMoney() == null ? 0 : jfSltBackData.getLendMoney();
                sltMoney = lendMoney * ratio / 100; //放款总金额
            } else if (copMode == CPC) {
                Float ratio = companyInfo.getSettlementPriceCpa();
                Integer clickNum = jfSltBackData.getClickNum() == null ? 0 : jfSltBackData.getClickNum();
                sltMoney = clickNum * ratio; //点击数
            } else if (copMode == CPA_CPS) {
                Float rCps = companyInfo.getSettlementPriceCps();
                Float rCpa = companyInfo.getSettlementPriceCpa();
                Integer registerNum = jfSltBackData.getRegisterNum() == null ? 0 : jfSltBackData.getRegisterNum();
                Double lendMoney = jfSltBackData.getLendMoney() == null ? 0 : jfSltBackData.getLendMoney();
                sltMoney = lendMoney * rCps / 100 + registerNum * rCpa;
            }

            jfSltBackData.setSltMoney(sltMoney);
        }


        for (JfSltBackData data : jfSltBackDataList) {
            if (data.getCreateTime().getTime() == jfSltBackData.getCreateTime().getTime()) {
                data = jfSltBackData;
                //参与uv
                //如果是天结算，把开始日期和结束日期置为相同
                if (data.getType() == DAY) {
                    data.setEndDate(data.getBeginDate());
                }
                Integer participateUv = countProductClickUv(data.getBeginDate(), data.getEndDate(), jfSltBackData.getType(), companyInfo.getId());
                data.setParticipateUv(participateUv);
                //uv价值
                if (participateUv == 0) {
                    data.setUvValue(0.0);
                } else {
                    data.setUvValue(data.getSltMoney() / participateUv);
                }
            }
        }

        return jfSltBackDataList;
    }

    @Override
    public List<FirstpartyDataChangeRecord> findBySettlementTimeAndCompanyId(Date settlementStartTime, Date settlementEndTime, Long companyId) {
        return jfBackDataRepository.findBySettlementTimeAndCompanyId(settlementStartTime, settlementEndTime, companyId);
    }

    @Override
    public List<JfSltBackData> findJfSltBackDataListByProcInstId(String procInstId) {
        return jfBackDataRepository.findAllByProcInstIdOrderByBeginDate(procInstId);
    }

    @Override
    public List<JfSltBackData> findJfSltBackDataListByProcInstIdAndType(String procInstId, Integer type) {
        return jfBackDataRepository.findAllByProcInstIdAndTypeOrderByBeginDate(procInstId, type);
    }

    /**
     * 查询公司所有产品参与uv
     *
     * @param beginDate
     * @param endDate
     * @param settlementType
     * @param companyId
     * @return
     */
    @Override
    public Integer countProductClickUv(Date beginDate, Date endDate, Integer settlementType, Long companyId) {
        List<ProductInfo> productInfoList = productInfoRepository.findAllByCompanyId(companyId);

        if (!productInfoList.isEmpty()) {
            List<Long> proIds = productInfoList.parallelStream().map(productInfo -> {
                return productInfo.getId();
            }).collect(Collectors.toList());
            return jfBackDataRepository.countCompanyProductClickUv(beginDate, endDate, proIds);
        }
        return 0;
    }

    @Override
    public void deletebyid(Long id) {
        if (id!=null)
            jfBackDataRepository.delete(id);
        else
            LogService.error("传入id为null,无法删除");
    }

    /**
     * 保存uv记录到loan_settlement_uv_record
     *
     * @return
     */
    @Override
    public void saveUvRecord(List<JfSltBackData> jfSltBackDataList) {
        for (JfSltBackData jfSltBackData : jfSltBackDataList) {
            Long jfId = jfSltBackData.getId();
            Long companyId = jfSltBackData.getCompanyId();
            Date beginDate = jfSltBackData.getBeginDate();
            Date endDate = jfSltBackData.getEndDate();
            Integer settlementType = jfSltBackData.getType();
            Double settlementAmount = jfSltBackData.getSltMoney();
            Double uvValue = jfSltBackData.getUvValue();
            Integer participateUv = jfSltBackData.getParticipateUv();
            //删除uv根据回数记录id
            if (jfId != null) {
                settlementUvRecordRepository.deleteAllByJfId(jfId);
            }
            List<ProductInfo> productInfoList = productInfoRepository.findAllByCompanyId(companyId);
            List<SettlementUvRecord> settlementUvRecordList = null;
            if (!productInfoList.isEmpty()) {
                List<Long> proIds = productInfoList.parallelStream().map(productInfo -> {
                    return productInfo.getId();
                }).collect(Collectors.toList());
                //查出产品所对应的uv
                settlementUvRecordList = jfBackDataRepository.countPerProductClickUv(beginDate, endDate, proIds);
                if (!settlementUvRecordList.isEmpty()) {
                    //这个时间的公司每条产品uv记录
                    settlementUvRecordList.forEach(settlementUvRecord -> {
                        settlementUvRecord.setBeginDate(beginDate);
                        settlementUvRecord.setEndDate(endDate);
                        settlementUvRecord.setCompanyId(companyId);
                        settlementUvRecord.setSettlementAmount(settlementAmount.floatValue());
                        settlementUvRecord.setSettlementType(settlementType);
                        settlementUvRecord.setUvValue(uvValue.floatValue());
                        settlementUvRecord.setIsGroup(1);//按产品分组
                        settlementUvRecord.setJfId(jfId);
                    });
                    //公司所有产品uv记录
                    SettlementUvRecord companyUvRecord = new SettlementUvRecord();
                    companyUvRecord.setBeginDate(beginDate);
                    companyUvRecord.setEndDate(endDate);
                    companyUvRecord.setCompanyId(companyId);
                    companyUvRecord.setSettlementAmount(settlementAmount.floatValue());
                    companyUvRecord.setSettlementType(settlementType);
                    companyUvRecord.setUvValue(uvValue.floatValue());
                    companyUvRecord.setParticipateUv(participateUv);
                    companyUvRecord.setIsGroup(0);//未按产品分组
                    companyUvRecord.setJfId(jfId);
                    companyUvRecord.setProductId(-1L);
                    settlementUvRecordList.add(companyUvRecord);
                }
            }
            settlementUvRecordRepository.save(settlementUvRecordList);
        }
    }


    @Override
    protected JpaRepository<JfSltBackData, Long> getRepository() {
        return jfBackDataRepository;
    }


    /**
     * 获取当前时间周一、周日 格式 yyyy-MM-dd
     *
     * @return
     */
    protected List<String> getCurrWeekBeginAndEnd() {
        List<String> dates = new ArrayList<>();
        Calendar calendar = Calendar.getInstance();

        calendar.set(calendar.DAY_OF_WEEK, calendar.MONDAY);
        dates.add(sdf.get().format(calendar.getTime())); //星期一

        calendar.set(Calendar.DATE, calendar.get(calendar.DATE) + 6);
        dates.add(sdf.get().format(calendar.getTime())); //星期日

        return dates;
    }

    /**
     * @param statDate 输入的日期
     * @return 一个星期的开始与结束  周期：每周四到每周三
     * @throws ParseException
     */
    protected List<String> getWeekByDate(Date statDate) {
        List<String> dates = new ArrayList<>();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(statDate);
        int week = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        if (week == 0) {
            week = 7;
        }

        int toLast4 = 0;
        if (week > 4) {
            toLast4 = week - 4;
        } else if (week < 4) {
            toLast4 = week + 3;
        }

        calendar.add(Calendar.DAY_OF_MONTH, -toLast4);
        String weekStart = sdf.get().format(calendar.getTime());
        calendar.add(Calendar.DAY_OF_MONTH, 6);
        String weekEnd = sdf.get().format(calendar.getTime());
        dates.add(weekStart);
        dates.add(weekEnd);
        return dates;
    }

}
